package com.tbynet.jwp.admin.post;

import java.math.BigInteger;
import java.util.*;

import com.jfinal.aop.Inject;
import com.jfinal.kit.Kv;
import com.jfinal.kit.Ret;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Page;
import com.tbynet.jwp.admin.AdminController;
import com.tbynet.jwp.framework.kit.DateKit;
import com.tbynet.jwp.framework.kit.JsoupKit;
import com.tbynet.jwp.framework.kit.StringKit;
import com.tbynet.jwp.service.spi.PostManager;
import com.tbynet.jwp.model.Postmeta;
import com.tbynet.jwp.model.Posts;
import com.tbynet.jwp.model.TermTaxonomy;
import com.tbynet.jwp.model.Terms;
import com.tbynet.jwp.repository.spi.*;

/**
 * 文章管理控制器
 * @ClassName: PostAdminController
 * @Description: 负责文章的增删改查、发布、回收站等操作
 * @Author: 佰亿互联
 * @Date: 2019年3月22日 上午12:23:05
 *
 * @Copyright: 2019 www.tbynet.com Inc. All rights reserved.
 * 注意: 本内容仅限于内部传阅，禁止外泄以及用于其他的商业目
 */
public class PostAdminController extends AdminController {

    // 依赖注入服务层
    @Inject
    private PostService postService;

    @Inject
    private TermService termService;

    @Inject
    private UserService userService;

    @Inject
    private CommentService commentService;

    @Inject
    private OptionService optionService;

    @Inject
    private PostCacheService postCacheService;

    @Inject
    private PostManager postManager;

    /**
     * 文章列表页面
     * 显示不同状态的文章统计数量
     */
    public void index() {
        try {
            set("all", postService.count(Posts.POST_TYPE_POST, null));
            set("publish", postService.count(Posts.POST_TYPE_POST, Posts.POST_STATUS_PUBLISH));
            set("sticky", postService.countStickyPosts());
            set("draft", postService.count(Posts.POST_TYPE_POST, Posts.POST_STATUS_DRAFT));
            set("pending", postService.count(Posts.POST_TYPE_POST, Posts.POST_STATUS_PENDING));
            set("trash", postService.count(Posts.POST_TYPE_POST, Posts.POST_STATUS_TRASH));

            // 添加筛选数据
            set("dateFilters", getDateFilters());
            set("categoryFilters", termService.getParents(TermTaxonomy.TAXONOMY_CATEGORY));
            set("tagFilters", termService.getTags());

            render("index.html");
        } catch (Exception e) {
            log.error("获取文章统计失败", e);
            renderError(500);
        }
    }

    /**
     * 文章搜索
     * 支持按状态和关键词搜索文章
     */
    public void search() {
        try {
            // 获取搜索参数
            String status = getPara("status");
            String q = getPara("q"); // 关键词
            String category = getPara("cat"); // 分类
            String tag = getPara("tag"); // 标签
            String month = getPara("m"); // 月份（YYYYMM格式）
            Boolean sticky = getParaToBoolean("sticky"); // 是否置顶

            // 使用PostManager进行高级搜索，带有缓存功能
            Page<Posts> page = postManager.advancedSearchPosts(
                    getPage(), getSize(), Posts.POST_TYPE_POST, status, q, category, tag, month, sticky);

            ok(Ret.by("data", page));
        } catch (Exception e) {
            log.error("搜索文章失败", e);
            fail("搜索文章失败: " + e.getMessage());
        }
    }

    /**
     * 创建文章页面
     * 显示文章编辑表单
     */
    public void create() {
        try {
            // 设置默认时间为当前时间
            set("date", new Date(System.currentTimeMillis()));
            // 获取分类目录树形结构
            set("categories", termService.getParents(TermTaxonomy.TAXONOMY_CATEGORY));
            render("create.html");
        } catch (Exception e) {
            log.error("加载创建文章页面失败", e);
            renderError(500);
        }
    }

    /**
     * 编辑文章页面
     * 显示指定文章的编辑表单
     */
    public void edit() {
        try {
            String postId = getPara("post");
            if (StrKit.isBlank(postId)) {
                fail("文章ID不能为空");
                return;
            }

            Posts post = postManager.getPostDetail(postId);
            if (post == null) {
                fail("文章不存在");
                return;
            }

            set("post", post);
            set("categories", termService.getParents(TermTaxonomy.TAXONOMY_CATEGORY));

            List<Terms> selectedCategories = termService.getTerms(post.getID(), TermTaxonomy.TAXONOMY_CATEGORY);
            // 创建选中分类的Set集合
            Set<BigInteger> selectedCategoryIds = new HashSet<>();
            if (selectedCategories != null) {
                for (Terms category : selectedCategories) {
                    selectedCategoryIds.add(category.getTermId());
                }
            }
            set("selectedCategoryIds", selectedCategoryIds);

            render("edit.html");
        } catch (Exception e) {
            log.error("加载编辑文章页面失败", e);
            fail("加载文章失败: " + e.getMessage());
        }
    }

    /**
     * 保存新文章
     * 处理文章创建请求
     */
    public void save() {
        try {
            // 获取表单参数并验证
            Posts post = buildPostFromRequest();
            if (post == null) {
                return; // 验证失败已在buildPostFromRequest中处理
            }

            // 构建文章元数据
            List<Postmeta> postmetas = buildPostmetasFromRequest();

            // 处理分类和标签
            String[] categories = getParaValues("category");
            List<String> tags = extractTags(getPara("tax_tag"), getPara("new_tag"));
            String format = getPara("post_format", "0");
            boolean sticky = getParaToBoolean("sticky", false);

            // 处理自定义字段
            String[] metaKeys = getParaValues("meta_key[]");
            String[] metaValues = getParaValues("meta_value[]");
            if (metaKeys != null && metaValues != null) {
                for (int i = 0; i < metaKeys.length; i++) {
                    if (StrKit.notBlank(metaKeys[i]) && StrKit.notBlank(metaValues[i])) {
                        Postmeta meta = new Postmeta();
                        meta.setMetaKey(metaKeys[i].trim());
                        meta.setMetaValue(metaValues[i].trim());
                        postmetas.add(meta);
                    }
                }
            }

            // 使用PostManager创建文章（包含事务）
            Ret result = postManager.createPost(post, postmetas, format,
                    categories, tags.toArray(new String[0]), sticky);

            if (result.isOk()) {
                ok(result);
            } else {
                fail(result.getStr("msg"));
            }
        } catch (Exception e) {
            log.error("保存文章失败", e);
            fail("保存文章失败: " + e.getMessage());
        }
    }

    /**
     * 更新文章
     * 处理文章编辑请求
     */
    public void update() {
        try {
            String postId = getPara("post");
            if (StrKit.isBlank(postId)) {
                fail("文章ID不能为空");
                return;
            }

            // 获取现有文章
            Posts post = postService.getPost(postId, Posts.POST_TYPE_POST);
            if (post == null) {
                fail("文章不存在");
                return;
            }

            // 更新文章基本信息
            updatePostFromRequest(post);

            // 构建文章元数据
            List<Postmeta> postmetas = buildPostmetasFromRequest();

            // 处理分类和标签
            String[] categories = getParaValues("category");
            List<String> tags = extractTags(getPara("tax_tag"), getPara("new_tag"));
            String format = getPara("post_format", "0");
            boolean sticky = getParaToBoolean("sticky", false);

            // 处理自定义字段
            String[] metaKeys = getParaValues("meta_key[]");
            String[] metaValues = getParaValues("meta_value[]");
            if (metaKeys != null && metaValues != null) {
                for (int i = 0; i < metaKeys.length; i++) {
                    if (StrKit.notBlank(metaKeys[i]) && StrKit.notBlank(metaValues[i])) {
                        Postmeta meta = new Postmeta();
                        meta.setMetaKey(metaKeys[i].trim());
                        meta.setMetaValue(metaValues[i].trim());
                        postmetas.add(meta);
                    }
                }
            }

            // 使用PostManager更新文章（包含事务）
            Ret result = postManager.updatePost(post, postmetas, format,
                    categories, tags.toArray(new String[0]), sticky);

            if (result.isOk()) {
                ok(result);
            } else {
                fail(result.getStr("msg"));
            }
        } catch (Exception e) {
            log.error("更新文章失败", e);
            fail("更新文章失败: " + e.getMessage());
        }
    }

    /**
     * 移至回收站
     * 将文章状态改为回收站状态
     */
    public void trash() {
        try {
            String postId = getPara("post");
            if (StrKit.isBlank(postId)) {
                fail("文章ID不能为空");
                return;
            }

            Posts post = postService.getById(postId);
            if (post == null) {
                fail("文章不存在");
                return;
            }

            post.setPostStatus(Posts.POST_STATUS_TRASH);

            if (post.update()) {
                // 清除缓存
                postCacheService.removePostFromCache(postId);
                ok(Ret.by("msg", "移到回收站成功").set("data", post.getID()));
            } else {
                fail("移到回收站失败，请联系管理员");
            }
        } catch (Exception e) {
            log.error("移至回收站失败", e);
            fail("操作失败: " + e.getMessage());
        }
    }

    /**
     * 从回收站恢复文章
     */
    public void restore() {
        try {
            String postId = getPara("post");
            if (StrKit.isBlank(postId)) {
                fail("文章ID不能为空");
                return;
            }

            Posts post = postService.getById(postId);
            if (post == null) {
                fail("文章不存在");
                return;
            }

            // 只能恢复回收站中的文章
            if (!Posts.POST_STATUS_TRASH.equals(post.getPostStatus())) {
                fail("只能恢复回收站中的文章");
                return;
            }

            post.setPostStatus(Posts.POST_STATUS_DRAFT);

            if (post.update()) {
                // 清除缓存
                postCacheService.removePostFromCache(postId);
                ok(Ret.by("msg", "恢复文章成功").set("data", post.getID()));
            } else {
                fail("恢复文章失败，请联系管理员");
            }
        } catch (Exception e) {
            log.error("恢复文章失败", e);
            fail("操作失败: " + e.getMessage());
        }
    }

    /**
     * 永久删除文章
     */
    public void delete() {
        try {
            String postId = getPara("post");
            if (StrKit.isBlank(postId)) {
                fail("文章ID不能为空");
                return;
            }

            // 使用PostManager删除文章（包含事务）
            Ret result = postManager.deletePost(postId);

            if (result.isOk()) {
                ok(result);
            } else {
                fail(result.getStr("msg"));
            }
        } catch (Exception e) {
            log.error("删除文章失败", e);
            fail("删除文章失败: " + e.getMessage());
        }
    }

    /**
     * 批量操作
     * 支持批量删除、移动回收站等操作
     */
    public void batch() {
        try {
            String action = getPara("action");
            String[] postIds = getParaValues("post_ids");

            if (postIds == null || postIds.length == 0) {
                fail("请选择要操作的文章");
                return;
            }

            if (StrKit.isBlank(action)) {
                fail("操作类型不能为空");
                return;
            }

            // 使用PostManager进行批量操作（包含事务）
            Ret result = postManager.batchOperatePosts(postIds, action);

            if (result.isOk()) {
                ok(result);
            } else {
                fail(result.getStr("msg"));
            }
        } catch (Exception e) {
            log.error("批量操作失败", e);
            fail("批量操作失败: " + e.getMessage());
        }
    }

    /**
     * 设置/取消置顶
     */
    public void sticky() {
        try {
            String postId = getPara("post");
            boolean sticky = getParaToBoolean("sticky", false);

            if (StrKit.isBlank(postId)) {
                fail("文章ID不能为空");
                return;
            }

            Ret result = postManager.setSticky(postId, sticky);

            if (result.isOk()) {
                ok(result);
            } else {
                fail(result.getStr("msg"));
            }
        } catch (Exception e) {
            log.error("设置置顶失败", e);
            fail("设置置顶失败: " + e.getMessage());
        }
    }

    // ============ 私有方法 ============

    /**
     * 从请求参数构建文章对象（用于创建）
     */
    private Posts buildPostFromRequest() throws Exception {
        String postTitle = getPara("post_title");
        if (StrKit.isBlank(postTitle)) {
            fail("文章标题不能为空");
            return null;
        }

        String postContent = getPara("post_content");
        if (StrKit.isBlank(postContent)) {
            fail("文章内容不能为空");
            return null;
        }

        Posts post = new Posts();
        post.setPostTitle(postTitle);

        // 处理固定链接
        String postName = getPara("post_name");
        if (StrKit.isBlank(postName)) {
            postName = StringKit.urlencode(postTitle);
        }
        post.setPostName(postName);

        post.setPostContent(postContent);
        post.setPostStatus(getPara("post_status", Posts.POST_STATUS_DRAFT));
        post.setPostType(Posts.POST_TYPE_POST);

        // 处理密码保护
        String visibility = getPara("post_visibility", "public");
        if ("password".equals(visibility)) {
            post.setPostPassword(getPara("post_password", ""));
        } else {
            post.setPostPassword("");
        }

        post.setPostAuthor(new BigInteger(getPara("post_author", "1")));

        // 处理日期
        String postDate = getPara("post_date");
        if (StrKit.notBlank(postDate)) {
            post.setPostDate(DateKit.toDate(postDate));
            post.setPostDateGmt(DateKit.toDate(getPara("post_date_gmt", postDate)));
        } else {
            Date now = new Date();
            post.setPostDate(now);
            post.setPostDateGmt(now);
        }

        post.setPostModified(new Date());
        post.setPostModifiedGmt(new Date());
        post.setPostExcerpt(getPara("post_excerpt", StringKit.substring(JsoupKit.getText(postContent), 240)));
        post.setPostParent(new BigInteger(getPara("post_parent", "0")));
        post.setPostContentFiltered("");
        post.setMenuOrder(getParaToInt("menu_order", 0));
        post.setCommentStatus(getPara("comment_status", "open"));
        post.setPingStatus(getPara("ping_status", "open"));
        post.setPinged(getPara("pinged", ""));
        post.setToPing(getPara("to_ping", ""));

        return post;
    }

    /**
     * 从请求参数更新文章对象（用于更新）
     */
    private void updatePostFromRequest(Posts post) throws Exception {
        String postTitle = getPara("post_title");
        if (StrKit.isBlank(postTitle)) {
            fail("文章标题不能为空");
            return;
        }

        String postContent = getPara("post_content");
        if (StrKit.isBlank(postContent)) {
            fail("文章内容不能为空");
            return;
        }

        post.setPostTitle(postTitle);

        // 处理固定链接
        String postName = getPara("post_name");
        if (StrKit.isBlank(postName)) {
            postName = StringKit.urlencode(postTitle);
        }
        post.setPostName(postName);

        post.setPostContent(postContent);
        post.setPostStatus(getPara("post_status"));

        // 处理密码保护
        String visibility = getPara("post_visibility", "public");
        if ("password".equals(visibility)) {
            post.setPostPassword(getPara("post_password", ""));
        } else {
            post.setPostPassword("");
        }

        post.setPostAuthor(new BigInteger(getPara("post_author", "1")));

        // 处理日期
        String postDate = getPara("post_date");
        if (StrKit.notBlank(postDate)) {
            post.setPostDate(DateKit.toDate(postDate));
            post.setPostDateGmt(DateKit.toDate(getPara("post_date_gmt", postDate)));
        }

        post.setPostModified(new Date());
        post.setPostModifiedGmt(new Date());
        post.setPostExcerpt(getPara("post_excerpt", StringKit.substring(JsoupKit.getText(postContent), 240)));
        post.setPostParent(new BigInteger(getPara("post_parent", "0")));
        post.setMenuOrder(getParaToInt("menu_order", 0));
        post.setCommentStatus(getPara("comment_status", "open"));
        post.setPingStatus(getPara("ping_status", "open"));
        post.setPinged(getPara("pinged", ""));
        post.setToPing(getPara("to_ping", ""));
    }

    /**
     * 从请求参数构建文章元数据列表
     */
    private List<Postmeta> buildPostmetasFromRequest() {
        List<Postmeta> postmetas = new ArrayList<>();

        // 编辑锁元数据
        Postmeta editLock = new Postmeta();
        editLock.setMetaKey(Postmeta._edit_lock);
        editLock.setMetaValue(System.currentTimeMillis() + ":" + getLoginUser().getID());
        postmetas.add(editLock);

        // 最后编辑者元数据
        Postmeta editLast = new Postmeta();
        editLast.setMetaKey(Postmeta._edit_last);
        editLast.setMetaValue(getLoginUser().getID().toString());
        postmetas.add(editLast);

        // 缩略图元数据
        String thumbnailId = getPara("_thumbnail_id");
        if (StrKit.notBlank(thumbnailId)) {
            Postmeta thumbnailMeta = new Postmeta();
            thumbnailMeta.setThumbnailId(thumbnailId);
            postmetas.add(thumbnailMeta);
        }

        // 文章形式
        String postFormat = getPara("post_format", "0");
        if (!"0".equals(postFormat)) {
            Postmeta formatMeta = new Postmeta();
            formatMeta.setMetaKey("post_format");
            formatMeta.setMetaValue(postFormat);
            postmetas.add(formatMeta);
        }


        return postmetas;
    }

    /**
     * 提取标签处理逻辑
     * 将标签字符串转换为标签列表
     */
    private List<String> extractTags(String taxTag, String newTag) {
        List<String> tags = new ArrayList<>();

        // 处理已有标签
        if (StrKit.notBlank(taxTag)) {
            for (String tag : taxTag.split("、")) {
                if (StrKit.notBlank(tag)) {
                    tags.add(tag.trim());
                }
            }
        }

        // 处理新标签
        if (StrKit.notBlank(newTag)) {
            for (String tag : newTag.split("、")) {
                if (StrKit.notBlank(tag)) {
                    tags.add(tag.trim());
                }
            }
        }

        return tags;
    }

    // 添加日期筛选选项方法
    private List<Kv> getDateFilters() {
        List<Kv> dateFilters = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();

        // 添加最近6个月的选项
        for (int i = 0; i < 6; i++) {
            int year = calendar.get(Calendar.YEAR);
            int month = calendar.get(Calendar.MONTH) + 1;
            String value = year + "" + (month < 10 ? "0" + month : month);
            String text = year + "年" + month + "月";

            dateFilters.add(Kv.by("value", value).set("text", text));

            // 上个月
            calendar.add(Calendar.MONTH, -1);
        }

        return dateFilters;
    }
}
